package com.cwnu.sw.cys.core.common.exception;

import com.cwnu.sw.cys.core.common.domain.vo.resp.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author jisam
 * @version 1.0
 * @contact "jisamchan@outlook.com"
 * @date 24/03/2025
 * @description 捕获全局异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 处理MethodArgumentNotValidException异常
     * @param e MethodArgumentNotValidException异常对象
     * @return ApiResult 包含错误信息和错误码的响应对象
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ApiResult<?> methodArgumentNotValidExceptionExceptionHandler(MethodArgumentNotValidException e) {
        StringBuilder errorMsg = new StringBuilder();
        e.getBindingResult().getFieldErrors().forEach(x -> errorMsg.append(x.getField()).append(x.getDefaultMessage()).append(","));
        String message = errorMsg.toString();
        log.info("validation parameters error！The reason is:{}", message);
        return ApiResult.fail(CommonErrorEnum.PARAM_VALID.getErrorCode(), message.substring(0, message.length() - 1));
    }

    /**
     * 处理BindException异常
     * @param e BindException异常对象
     * @return ApiResult 包含错误信息和错误码的响应对象
     */
    @ExceptionHandler(value = BindException.class)
    public ApiResult<?> bindException(BindException e) {
        StringBuilder errorMsg = new StringBuilder();
        e.getBindingResult().getFieldErrors().forEach(x -> errorMsg.append(x.getField()).append(x.getDefaultMessage()).append(","));
        String message = errorMsg.toString();
        log.info("validation parameters error！The reason is:{}", message);
        return ApiResult.fail(CommonErrorEnum.PARAM_VALID.getErrorCode(), message.substring(0, message.length() - 1));
    }

    /**
     * 处理NullPointerException异常
     * @param e NullPointerException异常对象
     * @return ApiResult 包含错误信息和错误码的响应对象
     */
    @ExceptionHandler(value = NullPointerException.class)
    public ApiResult<?> exceptionHandler(NullPointerException e) {
        log.error("null point exception！The reason is: ", e);
        return ApiResult.fail(CommonErrorEnum.SYSTEM_ERROR);
    }

    /**
     * 处理Exception异常
     * @param e Exception异常对象
     * @return ApiResult 包含错误信息和错误码的响应对象
     */
    @ExceptionHandler(value = Exception.class)
    public ApiResult<?> systemExceptionHandler(Exception e) {
        log.error("system exception！The reason is：{}", e.getMessage(), e);
        return ApiResult.fail(CommonErrorEnum.SYSTEM_ERROR);
    }

    /**
     * 处理BusinessException异常
     * @param e BusinessException异常对象
     * @return ApiResult 包含错误信息和错误码的响应对象
     */
    @ExceptionHandler(value = BusinessException.class)
    public ApiResult<?> businessExceptionHandler(BusinessException e) {
        log.info("business exception！The reason is：{}", e.getMessage(), e);
        return ApiResult.fail(e.getErrorCode(), e.getMessage());
    }

    /**
     * 处理HttpRequestMethodNotSupportedException异常
     * @param e HttpRequestMethodNotSupportedException异常对象
     * @return ApiResult 包含错误信息和错误码的响应对象
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ApiResult<Void> handleException(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage(), e);
        return ApiResult.fail(-1, String.format("不支持'%s'请求", e.getMethod()));
    }

    /**
     * 处理FrequencyControlException异常
     * @param e FrequencyControlException异常对象
     * @return ApiResult 包含错误信息和错误码的响应对象
     */
    @ExceptionHandler(value = FrequencyControlException.class)
    public ApiResult<?> frequencyControlExceptionHandler(FrequencyControlException e) {
        log.info("frequencyControl exception！The reason is：{}", e.getMessage(), e);
        return ApiResult.fail(e.getErrorCode(), e.getMessage());
    }
}
